import libtcodpy as libtcod
import math
import fire
from Tile import *
from Base_Object import *
import coordinates
from message import *

class Rect:
    # a rectangle on the map.
    def __init__(self, x, y, w, h):
        self.x1 = x
        self.y1 = y
        self.x2 = x + w
        self.y2 = y + h

    def center(self):
        center_x = (self.x1 + self.x2) / 2
        center_y = (self.y1 + self.y2) / 2
        return (center_x, center_y)

    def isIntersecting(self, other):
        return (self.x1 <= other.x2 and self.x2 >= other.x1 and
                self.y1 <=other.y2 and self.y2 >= other.y1)



class Fighter:
    def __init__(self, hp, defense, power, death_function = None):
        self.death_function = death_function
        self.max_hp = hp
        self.hp = hp
        self.defense = defense
        self.power = power

    def take_damage(self, damage):
        if damage > 0:
            self.hp -=damage
        if self.hp <= 0:
            function = self.death_function
            if function is not None:
                function(self.owner)

    def attack(self, target):
        # from firsttry import message
        damage = self.power - target.fighter.defense

        if damage > 0:
            message(self.owner.name.capitalize() + " attacks " + target.name + " for " + str(damage) + " hit points.", libtcod.white)
            target.fighter.take_damage(damage)
        else:
            message(self.owner.name.capitalize() + " attacks " + target.name + " but it has no effect!", libtcod.white)

    def heal(self, amount):
        # heal by the given amount, without going over the maximum
        self.hp += amount
        if self.hp > self.max_hp:
            self.hp = self.max_hp

class BasicMonster:
    def take_turn(self, fov_map, map, objects, player):
        monster = self.owner
        if libtcod.map_is_in_fov(fov_map, monster.x, monster.y):
            if monster.distance_to(player) >= 2:
                monster.move_towards( map, objects, player.x, player.y)

            elif player.fighter and player.fighter.hp > 0:
                monster.fighter.attack(player)

class SmartMonster:

    #The last place the player saw the monster
    playerLastSeen = None
    pathToPlayer = None

    def take_turn(self, fov_map, map, objects, player):
        monster = self.owner

        if libtcod.map_is_in_fov(fov_map, monster.x, monster.y):
            self.playerLastSeen = coordinates.coordinate(player.x, player.y)
            # print "I see you"

            if coordinates.pythagorean_dist(coordinates.coordinate(player.x, player.y), coordinates.coordinate(monster.x, monster.y)) <= math.sqrt(2):
                if player.fighter and player.fighter.hp > 0:
                    monster.fighter.attack(player)

        if self.playerLastSeen is not None:
            import AI_Utils
            startPos = coordinates.coordinate(monster.x, monster.y)
            endPos = coordinates.coordinate(self.playerLastSeen.x, self.playerLastSeen.y)

            self.pathToPlayer = AI_Utils.a_star_search(map, startPos, endPos, use_unexplored_tiles=True)
            # self.pathToPlayer.reverse()

            if self.pathToPlayer is not None and len(self.pathToPlayer) > 1:
                startMove = self.pathToPlayer[0]
                endMove = self.pathToPlayer[1]

                moveX = endMove.x - startMove.x
                moveY = endMove.y - startMove.y

                # print str(monster.x) + "," + str(monster.y) + ": " + str(moveX) + ", " + str(moveY)

                monster.move(map, objects, moveX, moveY)

            # if self.playerLastSeen[0] == monster.x and self.playerLastSeen[1] == monster.y:
            #     self.playerLastSeen = None
            #     return
            #
            # dX = self.playerLastSeen[0] - monster.x
            # dY = self.playerLastSeen[1] - monster.y
            #
            # if math.fabs(dX) + math.fabs(dY) >= 2:
            #
            # elif player.fighter and player.fighter.hp > 0:

# an item that can be picked up and used
class Item:
    def __init__(self, use_function=None):
        self.use_function = use_function

    def use(self, inventory):
        if self.use_function is None:
            message('The ' + self.owner.name + ' cannot be used.')
        else:
            if self.use_function != 'cancelled':
                self.use_function()
                inventory.remove(self.owner)

    def pick_up(self, inventory, objects):
        if len(inventory) >= 26:
            message('Your inventory is full, cannot pick up ' + self.owner.name + '.', libtcod.red)
        else:
            inventory.append(self.owner)
            objects.remove(self.owner)
            message('You picked up a ' + self.owner.name + '!', libtcod.green)
